////
// @file table.h
// @brief
// 存储管理
//
// @author niexw
// @email niexiaowen@uestc.edu.cn
//
#ifndef __DB_TABLE_H__
#define __DB_TABLE_H__

#include <string>
#include <vector>
#include "./record.h"
#include "./schema.h"
#include "./block.h"
#include "./buffer.h"

namespace db {

////
// @brief
// 表操作接口
//
class Table
{
  public:
    // 表的迭代器
    struct BlockIterator
    {
        DataBlock block;
        BufDesc *bufDesc;

        BlockIterator();
        ~BlockIterator();
        BlockIterator(const BlockIterator &other);

        // 前置操作
        BlockIterator &operator++();
        // 后置操作
        BlockIterator operator++(int);
        // 数据块指针
        DataBlock *operator->();

        // 释放buffer
        void release();
    };

    struct RecordIterator
    {
        Record record = Record();
        unsigned short index = 0;
        BlockIterator blockIt = BlockIterator();

        RecordIterator();
        ~RecordIterator();
        RecordIterator(const RecordIterator &other);
        void attach(Table*);

        // 前置操作
        RecordIterator &operator++();
        // 后置操作
        RecordIterator operator++(int);
        // 加减操作
        RecordIterator &operator+=(int);
        // 数据块指针
        Record *operator->();
    };

  public:
    std::string name_;   // 表名
    RelationInfo *info_; // 表的元数据
    unsigned int maxid_; // 最大的blockid
    unsigned int idle_;  // 空闲链
    unsigned int first_; // 数据链

  public:
    Table()
        : info_(nullptr)
        , maxid_(0)
        , idle_(0)
        , first_(0)
    {}

    // 打开一张表
    int open(const char *name);

    // 定位一个block后，插入一条记录
    int insert(unsigned int blkId, const std::vector<struct iovec> &iov);
    int insert(const std::vector<struct iovec> &iov);   // BTree API
    int update(unsigned int blkId, const std::vector<struct iovec> &iov);
    int update(const std::vector<struct iovec> &iov);   // BTree API
    int remove(unsigned int blkId, void *keyBuf, unsigned int len); // NOLINT(*-use-trailing-return-type)
    int remove(void *keyBuf, unsigned int len);         // BTree API

    RecordIterator beginRecord();
    RecordIterator endRecord();

    // 采用枚举的方式定位一个key在哪个block
    unsigned int locate(void *keyBuf, unsigned int len);
    unsigned int locateBTree(void *keyBuf, unsigned int len);

    // 返回表上总的记录数目
    size_t recordCount() const;
    // 返回表上数据块个数
    unsigned int dataCount() const;
    // 返回表上空闲块个数
    unsigned int idleCount() const;

    // block迭代器
    BlockIterator beginBlock();
    BlockIterator endBlock();

    // 新分配一个block，返回blockid，但并没有将该block插入数据链上
    unsigned int allocate();
    // 回收一个block
    void deallocate(unsigned int blockid);
};

inline bool
operator==(const Table::BlockIterator &x, const Table::BlockIterator &y)
{
    if (x.block.table_ != y.block.table_)
        return false;
    if (x.block.buffer_ == y.block.buffer_)
        return true;
    return false;
}

inline bool
operator!=(const Table::BlockIterator &x, const Table::BlockIterator &y)
{
    if (x.block.table_ != y.block.table_)
        return true;
    if (x.block.buffer_ != y.block.buffer_)
        return true;
    return false;
}

inline bool operator==(const Table::RecordIterator &x, const Table::RecordIterator &y) {
    if (x.blockIt != y.blockIt)
        return false;
    if (x.index != y.index)
        return false;
    return true;
}
inline bool operator!=(const Table::RecordIterator &x, const Table::RecordIterator &y) {
    if (x.blockIt == y.blockIt)
        return true;
    if (x.index == y.index)
        return true;
    return false;
}

} // namespace db

#endif // __DB_TABLE_H__
